home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
libs
/
3dvect39
/
mod.asm
< prev
next >
Wrap
Assembly Source File
|
1994-10-30
|
34KB
|
1,084 lines
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; MOD playback routine using 'GUS' lowlevel GUS & SB routines.
;
; Written by: John McCarthy
; 1316 Redwood Lane
; Pickering, Ontario.
; Canada, Earth, Milky Way (for those out-of-towners)
; L1X 1C5
;
; Most of the main MOD effects are implemented, Vibrato, Tone sliding, Volume
; Sliding and such. I seem to have a little problem with the sample loop. I
; dont think I am loading the loop start and end pointers correctly. (I have
; one mod that clicks annoyingly when playing a certin sample. But I can't
; figure out why the other players I have don't click when this sample is
; played). All looped samples are bi-directionally looped. This means that
; intruments sound great when looped, but voices get really screwed up. You
; can change the loop_bi option in the sample loading routine. Anyway, I
; coded this thing in about 3 days so don't expect too much.
;
; 4,6 or 8 channel mods are supported. But only "31 sample" mods can be
; played. Sorry - 15 sample mods not supported.
;
; Send Me a Postcard!
;
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
.386p
code32 segment para public use32
assume cs:code32, ds:code32
include pmode.ext
include gus.ext
include irq.ext
public _mod_init, _mod_uninit, _mod_load, _mod_play, _mod_stop, _mod_sample_play
public _ordmod, _currow
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; DATA
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; memory usage
;
; samples first: (496 bytes)
; length dd
; volume dd ; xxqqyyzz qq = loop yes/no, zz = fine tune, yy = volume
; loopstart dd
; loopend dd
;
; pattern order (128 bytes)
;
; db 128 dup (0)
;
; patterns
;
; db channels*4*64
; Mod Pattern Info
;
;7654-3210 7654-3210 7654-3210 7654-3210
;wwww xxxxxxxxxxxxxx yyyy zzzzzzzzzzzzzz
;
; wwwwyyyy (8 bits) is the sample for this channel/division (0 = no sample)
;xxxxxxxxxxxx (12 bits) is the sample's period (or effect parameter)
;zzzzzzzzzzzz (12 bits) is the effect for this channel/division
sambase dd 0 ; offset to sample data table
ordbase dd 0 ; offset to pattern order
patterns dd 0 ; offset to patterns
patternend dd 0
whendone dd _ret ; routine to call when done module
_ordmod db 0 ; current order position (0-127 tables)
_currow db 0 ; current row (0-63) set, but never used
ordwidth dd 0 ; 4,6 or 8
ordsize db 0 ; number of patterns
currow dd 0 ; order position row (offset in memory)
lastord db 0 ; when does song end
panloc db 0 ; base of ping-pong pan
tempo db 0
tempoc db 0
rowleft db 0 ; coloumns left before next order
break db 0
cursamp db 8 dup (0) ; sample for channel
modvol db 8 dup (0) ; volume for channel (0-64)
effect dw 8 dup (0) ; channel effect
portto dw 8 dup (0)
period dw 8 dup (0) ; current sample period
portparm db 8 dup (0)
vibpos db 8 dup (0)
vibparm db 8 dup (0)
arp dd 16 dup (0) ; dw index,arp,arp,arp
align 4
whichmodcontrol dd -1 ; irq timing control number
pantbl db 3,3,3,4,4,5,6,7,8,9,10,11,11,12,12,12
db 12,12,12,11,11,10,9,8,7,6,5,4,4,3,3,3
db 3,3,3,4,4,5,6,7,8,9,10,11,11,12,12,12
db 12,12,12,11,11,10,9,8,7,6,5,4,4,3,3,3
db 3,3,3,4,4,5,6,7,8,9,10,11,11,12,12,12
db 12,12,12,11,11,10,9,8,7,6,5,4,4,3,3,3
db 3,3,3,4,4,5,6,7,8,9,10,11,11,12,12,12
db 12,12,12,11,11,10,9,8,7,6,5,4
sintable db 0,25,50,74,98,120,142,162,180,197,212,225
db 236,244,250,254,255,254,250,244,236,225
db 212,197,180,162,142,120,98,74,50,25
pitchtbl dw 828 dup (0)
;ax = 5.6865
;
;FOR z = 5 - 1 / 12 / 16 TO 0 STEP -1 / 12 / 16
; PRINT "dw "; INT(2 ^ (ax + z) + .5)
; q = q + 1
;NEXT z
;
;END
periods label word
dw 1642,1636,1630,1624,1619,1613,1607,1601,1595,1590,1584,1578,1572,1567,1561
dw 1556,1550,1544,1539,1533,1528,1522,1517,1511,1506,1500,1495,1490,1484,1479
dw 1474,1468,1463,1458,1452,1447,1442,1437,1432,1426,1421,1416,1411,1406,1401
dw 1396,1391,1386,1381,1376,1371,1366,1361,1356,1351,1346,1341,1337,1332,1327
dw 1322,1317,1313,1308,1303,1299,1294,1289,1285,1280,1275,1271,1266,1262,1257
dw 1253,1248,1244,1239,1235,1230,1226,1221,1217,1213,1208,1204,1199,1195,1191
dw 1187,1182,1178,1174,1170,1165,1161,1157,1153,1149,1144,1140,1136,1132,1128
dw 1124,1120,1116,1112,1108,1104,1100,1096,1092,1088,1084,1080,1076,1072,1069
dw 1065,1061,1057,1053,1049,1046,1042,1038,1034,1031,1027,1023,1020,1016,1012
dw 1009,1005,1001,998,994,991,987,983,980,976,973,969,966,962,959,955,952,949
dw 945,942,938,935,932,928,925,922,918,915,912,908,905,902,899,895,892,889,886
dw 882,879,876,873,870,867,864,860,857,854,851,848,845,842,839,836,833,830,827
dw 824,821,818,815,812,809,806,803,801,798,795,792,789,786,783,781,778,775,772
dw 769,767,764,761,758,756,753,750,747,745,742,739,737,734,731,729,726,724,721
dw 718,716,713,711,708,706,703,700,698,695,693,690,688,685,683,680,678,676,673
dw 671,668,666,664,661,659,656,654,652,649,647,645,642,640,638,635,633,631,629
dw 626,624,622,620,617,615,613,611,608,606,604,602,600,598,595,593,591,589,587
dw 585,583,581,578,576,574,572,570,568,566,564,562,560,558,556,554,552,550,548
dw 546,544,542,540,538,536,534,532,530,529,527,525,523,521,519,517,515,513,512
dw 510,508,506,504,502,501,499,497,495,493,492,490,488,486,485,483,481,479,478
dw 476,474,473,471,469,467,466,464,462,461,459,457,456,454,453,451,449,448,446
dw 444,443,441,440,438,436,435,433,432,430,429,427,426,424,423,421,419,418,416
dw 415,413,412,411,409,408,406,405,403,402,400,399,397,396,395,393,392,390,389
dw 387,386,385,383,382,381,379,378,376,375,374,372,371,370,368,367,366,364,363
dw 362,360,359,358,357,355,354,353,351,350,349,348,346,345,344,343,341,340,339
dw 338,337,335,334,333,332,331,329,328,327,326,325,323,322,321,320,319,318,317
dw 315,314,313,312,311,310,309,308,306,305,304,303,302,301,300,299,298,297,296
dw 294,293,292,291,290,289,288,287,286,285,284,283,282,281,280,279,278,277,276
dw 275,274,273,272,271,270,269,268,267,266,265,264,263,262,261,260,260,259,258
dw 257,256,255,254,253,252,251,250,249,249,248,247,246,245,244,243,242,241,241
dw 240,239,238,237,236,235,235,234,233,232,231,230,230,229,228,227,226,225,225
dw 224,223,222,221,221,220,219,218,217,217,216,215,214,214,213,212,211,211,210
dw 209,208,207,207,206,205,205,204,203,202,202,201,200,199,199,198,197,197,196
dw 195,194,194,193,192,192,191,190,190,189,188,188,187,186,186,185,184,184,183
dw 182,182,181,180,180,179,178,178,177,176,176,175,174,174,173,173,172,171,171
dw 170,170,169,168,168,167,166,166,165,165,164,164,163,162,162,161,161,160,159
dw 159,158,158,157,157,156,155,155,154,154,153,153,152,152,151,150,150,149,149
dw 148,148,147,147,146,146,145,145,144,144,143,143,142,142,141,140,140,139,139
dw 138,138,137,137,136,136,136,135,135,134,134,133,133,132,132,131,131,130,130
dw 129,129,128,128,127,127,127,126,126,125,125,124,124,123,123,122,122,122,121
dw 121,120,120,119,119,119,118,118,117,117,116,116,116,115,115,114,114,114,113
dw 113,112,112,112,111,111,110,110,110,109,109,108,108,108,107,107,106,106,106
dw 105,105,104,104,104,103,103,103,102,102,102,101,101,100,100,100,99,99,99,98
dw 98,98,97,97,97,96,96,95,95,95,94,94,94,93,93,93,92,92,92,91,91,91,90,90,90
dw 89,89,89,89,88,88,88,87,87,87,86,86,86,85,85,85,84,84,84,84,83,83,83,82,82
dw 82,81,81,81,81,80,80,80,79,79,79,79,78,78,78,77,77,77,77,76,76,76,76,75,75
dw 75,74,74,74,74,73,73,73,73,72,72,72,72,71,71,71,71,70,70,70,69,69,69,69,68
dw 68,68,68,68,67,67,67,67,66,66,66,66,65,65,65,65,64,64,64,64,63,63,63,63,63
dw 62,62,62,62,61,61,61,61,61,60,60,60,60,60,59,59,59,59,58,58,58,58,58,57,57
;ax = 11.08082
;
;FOR z = 0 TO 5 STEP 1 / 12 / 16
; PRINT "dw "; INT(2 ^ (ax + z) + .5)
; q = q + 1
;NEXT z
;
;END
rawfreq label word
dw 2166,2174,2182,2190,2198,2205,2213,2221,2229,2238,2246,2254,2262,2270,2278
dw 2287,2295,2303,2311,2320,2328,2337,2345,2354,2362,2371,2379,2388,2396,2405
dw 2414,2422,2431,2440,2449,2458,2467,2476,2484,2493,2502,2512,2521,2530,2539
dw 2548,2557,2567,2576,2585,2594,2604,2613,2623,2632,2642,2651,2661,2671,2680
dw 2690,2700,2709,2719,2729,2739,2749,2759,2769,2779,2789,2799,2809,2819,2829
dw 2840,2850,2860,2870,2881,2891,2902,2912,2923,2933,2944,2955,2965,2976,2987
dw 2998,3008,3019,3030,3041,3052,3063,3074,3085,3097,3108,3119,3130,3142,3153
dw 3164,3176,3187,3199,3210,3222,3234,3245,3257,3269,3281,3293,3304,3316,3328
dw 3340,3353,3365,3377,3389,3401,3414,3426,3438,3451,3463,3476,3488,3501,3514
dw 3526,3539,3552,3565,3578,3591,3604,3617,3630,3643,3656,3669,3682,3696,3709
dw 3723,3736,3750,3763,3777,3790,3804,3818,3832,3845,3859,3873,3887,3901,3916
dw 3930,3944,3958,3972,3987,4001,4016,4030,4045,4059,4074,4089,4104,4118,4133
dw 4148,4163,4178,4194,4209,4224,4239,4255,4270,4285,4301,4316,4332,4348,4363
dw 4379,4395,4411,4427,4443,4459,4475,4491,4507,4524,4540,4557,4573,4590,4606
dw 4623,4640,4656,4673,4690,4707,4724,4741,4758,4776,4793,4810,4828,4845,4863
dw 4880,4898,4915,4933,4951,4969,4987,5005,5023,5041,5059,5078,5096,5115,5133
dw 5152,5170,5189,5208,5227,5245,5264,5284,5303,5322,5341,5360,5380,5399,5419
dw 5438,5458,5478,5498,5517,5537,5557,5578,5598,5618,5638,5659,5679,5700,5720
dw 5741,5762,5783,5803,5824,5846,5867,5888,5909,5931,5952,5974,5995,6017,6039
dw 6060,6082,6104,6126,6149,6171,6193,6216,6238,6261,6283,6306,6329,6352,6375
dw 6398,6421,6444,6467,6491,6514,6538,6561,6585,6609,6633,6657,6681,6705,6729
dw 6754,6778,6803,6827,6852,6877,6902,6926,6952,6977,7002,7027,7053,7078,7104
dw 7129,7155,7181,7207,7233,7259,7286,7312,7338,7365,7392,7418,7445,7472,7499
dw 7526,7553,7581,7608,7636,7663,7691,7719,7747,7775,7803,7831,7859,7888,7916
dw 7945,7974,8003,8031,8061,8090,8119,8148,8178,8207,8237,8267,8297,8327,8357
dw 8387,8417,8448,8478,8509,8540,8571,8602,8633,8664,8695,8727,8758,8790,8822
dw 8854,8886,8918,8950,8983,9015,9048,9080,9113,9146,9179,9212,9246,9279,9313
dw 9346,9380,9414,9448,9482,9517,9551,9586,9620,9655,9690,9725,9760,9796,9831
dw 9867,9902,9938,9974,10010,10046,10083,10119,10156,10192,10229,10266,10303
dw 10341,10378,10416,10453,10491,10529,10567,10605,10644,10682,10721,10759
dw 10798,10837,10877,10916,10955,10995,11035,11075,11115,11155,11195,11236
dw 11276,11317,11358,11399,11440,11482,11523,11565,11607,11649,11691,11733
dw 11776,11818,11861,11904,11947,11990,12034,12077,12121,12165,12209,12253
dw 12297,12342,12386,12431,12476,12521,12566,12612,12657,12703,12749,12795
dw 12841,12888,12935,12981,13028,13075,13123,13170,13218,13266,13314,13362
dw 13410,13459,13507,13556,13605,13654,13704,13753,13803,13853,13903,13953
dw 14004,14054,14105,14156,14207,14259,14310,14362,14414,14466,14519,14571
dw 14624,14677,14730,14783,14836,14890,14944,14998,15052,15107,15161,15216
dw 15271,15326,15382,15437,15493,15549,15606,15662,15719,15775,15833,15890
dw 15947,16005,16063,16121,16179,16238,16296,16355,16415,16474,16533,16593
dw 16653,16714,16774,16835,16896,16957,17018,17079,17141,17203,17265,17328
dw 17391,17453,17517,17580,17644,17707,17771,17836,17900,17965,18030,18095
dw 18161,18226,18292,18358,18425,18491,18558,18625,18693,18760,18828,18896
dw 18965,19033,19102,19171,19240,19310,19380,19450,19520,19591,19662,19733
dw 19804,19876,19948,20020,20092,20165,20238,20311,20384,20458,20532,20606
dw 20681,20756,20831,20906,20982,21058,21134,21210,21287,21364,21441,21519
dw 21597,21675,21753,21832,21911,21990,22069,22149,22229,22310,22390,22471
dw 22553,22634,22716,22798,22881,22963,23047,23130,23214,23298,23382,23466
dw 23551,23636,23722,23808,23894,23980,24067,24154,24241,24329,24417,24505
dw 24594,24683,24772,24862,24952,25042,25132,25223,25315,25406,25498,25590
dw 25683,25776,25869,25962,26056,26151,26245,26340,26435,26531,26627,26723
dw 26820,26917,27014,27112,27210,27308,27407,27506,27606,27705,27806,27906
dw 28007,28108,28210,28312,28415,28517,28620,28724,28828,28932,29037,29142
dw 29247,29353,29459,29566,29673,29780,29888,29996,30104,30213,30322,30432
dw 30542,30652,30763,30875,30986,31098,31211,31324,31437,31551,31665,31779
dw 31894,32010,32125,32241,32358,32475,32593,32710,32829,32947,33067,33186
dw 33306,33427,33548,33669,33791,33913,34036,34159,34282,34406,34531,34655
dw 34781,34907,35033,35160,35287,35414,35542,35671,35800,35929,36059,36190
dw 36321,36452,36584,36716,36849,36982,37116,37250,37385,37520,37656,37792
dw 37929,38066,38204,38342,38481,38620,38759,38900,39040,39181,39323,39465
dw 39608,39751,39895,40039,40184,40330,40475,40622,40769,40916,41064,41213
dw 41362,41511,41662,41812,41963,42115,42268,42420,42574,42728,42882,43037
dw 43193,43349,43506,43663,43821,43980,44139,44299,44459,44620,44781,44943
dw 45105,45269,45432,45597,45762,45927,46093,46260,46427,46595,46764,46933
dw 47103,47273,47444,47615,47788,47961,48134,48308,48483,48658,48834,49011
dw 49188,49366,49544,49724,49903,50084,50265,50447,50629,50812,50996,51181
dw 51366,51552,51738,51925,52113,52301,52491,52680,52871,53062,53254,53447
dw 53640,53834,54029,54224,54420,54617,54815,55013,55212,55412,55612,55813
dw 56015,56218,56421,56625,56830,57035,57242,57449,57656,57865,58074,58284
dw 58495,58707,58919,59132,59346,59561,59776,59992,60209,60427,60645,60865
dw 61085,61306,61528,61750,61973
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Main playback routine called by IRQ routine
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; mr_???? main mod playing effects handler (called only as often as tempo requires)
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
mr_modpolling:
dec tempoc
jnz fx_between_rows
inc panloc
and panloc,3fh
mov esi,currow
xor ebp,ebp
mr_mainloop:
movzx eax,panloc
lea eax,[eax+ebp*4]
mov bl,pantbl[eax+ebp*4]
mov _vcpan[ebp],bl
or _vccmnd[ebp],pan
lodsw
xchg al,ah
mov bl,ah
and ah,0fh
mov cx,ax
lodsw
xchg al,ah
mov bh,ah
and ah,0fh
mov dx,ax
mov effect[ebp*2],dx
and bl,0F0h
shr bh,4
or bl,bh
je mr_nosample
and ebx,0ffh ; play new sample
dec ebx
mov edi,ebx
mov cursamp[ebp],bl
shl edi,4
add edi,sambase
mov eax,[edi]
mov _vcsbeg[ebp*4],eax
mov eax,[edi+8]
mov _vclbeg[ebp*4],eax
mov eax,[edi+12]
mov _vclend[ebp*4],eax
mov al,byte ptr [edi+4+1]
mov modvol[ebp],al
mov al,modvol[ebp]
cmp al,63
jb short mr_novol64
mov al,63
mr_novol64:
shr al,2
mov _vcvol[ebp],al
mov al,byte ptr [edi+4+2]
mov _vccntrl[ebp],al
or _vccmnd[ebp],play+vol+freq+pan
mr_nosample:
test cx,cx ; set new pitch
je short mr_testtempo
mov portto[ebp*2],cx
cmp dh,3
je short mr_testtempo
mov period[ebp*2],cx
sub ecx,57
and ecx,0fffeh
mov ax,pitchtbl[ecx]
mov _vcfreq[ebp*2],ax
or _vccmnd[ebp],freq
mr_testtempo:
test dx,dx
je mr_done_channel
cmp dh,0fh ; set tempo
jne short mr_jump
test dl,dl
je mr_done_channel
cmp dl,31
ja short mr_setbpm
mov tempo,dl
mov tempoc,dl
jmp mr_done_channel
mr_setbpm:
mov eax,900
movzx ebx,dl
xor edx,edx
div bx
mov tempo,al
mov tempoc,al
jmp mr_done_channel
mr_jump:
cmp dh,0bh ; jump to new pattern
jne short mr_break
mov _ordmod,dl
mov rowleft,1
jmp mr_done_channel
mr_break:
cmp dh,0dh ; pattern break
jne short mr_setvolume
mov dh,dl
and dl,0fh
shr dh,4
add dh,dh
add dl,dh
shl dh,2
add dl,dh
mov break,dl
mov rowleft,1
jmp mr_done_channel
mr_setvolume:
cmp dh,0ch ; set volume
jne short mr_tone_slide
mov modvol[ebp],dl
cmp dl,63
jbe short mr_not_6chan4
mov dl,63
mr_not_6chan4:
shr dl,2
mov _vcvol[ebp],dl
or _vccmnd[ebp],vol
jmp mr_done_channel
mr_tone_slide:
cmp dh,3 ; tone slide
jne short mr_init_vibrato
test dl,dl
jne short mr_notlastslide
mov dl,[ebp+portparm]
mr_notlastslide:
mov [ebp+portparm],dl
mov [ebp*2+effect],dx
and _vccmnd[ebp],-1-play
jmp mr_done_channel
mr_init_vibrato:
cmp dh,4 ; initialize vibrato
jne short mr_initarp
mov al,[ebp+vibparm]
mov ah,al
and al,0fh
and ah,0f0h
test dl,0fh
jne short mr_okdepth
or dl,al
mr_okdepth:
test dl,0f0h
jne short mr_okrate
or dl,ah
mr_okrate:
mov [ebp+vibparm],dl
mov [ebp*2+effect],dx
test cx,cx
je mr_done_channel
mov [ebp+vibpos],0
jmp mr_done_channel
mr_initarp:
cmp dh,0 ; initialize arpeggio
jne mr_more_effects
mov dh,dl
and dl,0fh
shr dh,4
xor ebx,ebx
mov ax,[ebp*2+period]
mr_scanperiod:
cmp ax,periods[ebx*2]
jae mr_set_arp
inc ebx
cmp ebx,930
jb short mr_scanperiod
mr_set_arp:
xor eax,eax
mov al,dh
shl eax,4
add eax,ebx
xor ecx,ecx
mov cl,dl
shl ecx,4
add ecx,ebx
mov bx,periods[ebx*2]
sub ebx,57
and ebx,0fffeh
mov bx,[pitchtbl+ebx]
mov word ptr [ebp*8+arp+2],bx
mov cx,periods[ecx*2]
sub ecx,57
and ecx,0fffeh
mov cx,[pitchtbl+ecx]
mov word ptr [ebp*8+arp+4],cx
mov ax,periods[eax*2]
sub eax,57
and eax,0fffeh
mov ax,[pitchtbl+eax]
mov word ptr [ebp*8+arp+6],ax
mov byte ptr [ebp*8+arp],0
jmp mr_done_channel
mr_more_effects:
; Put more effects here
; dh = effect
; dl = data
mr_done_channel:
inc ebp
cmp ordwidth,ebp
jne mr_mainloop
mov currow,esi ; save current pattern position
inc _currow
dec rowleft ; how many rows left?
jnz mr_nonewrow
inc _ordmod ; done pattern, find next
movzx eax,_ordmod
cmp al,lastord ; done song?
jne short mr_moresong
xor eax,eax ; set up to loop forever unless user calls _mod_stop
mov _ordmod,al
call [whendone] ; call user routine when finished mod
mr_moresong:
add eax,ordbase
movzx eax,byte ptr [eax]
shl eax,10
cmp ordwidth,8
jne short mr_not_8chan
shl eax,1
mr_not_8chan:
cmp ordwidth,6
jne short mr_not_6chan
mov ebx,eax
shr ebx,1
add eax,ebx
mr_not_6chan:
add eax,patterns
mov currow,eax
movzx eax,break
mov ebx,ordwidth
shl eax,4
cmp ebx,8
jne short mr_not_8chanbrk
shl eax,1
mr_not_8chanbrk:
cmp ebx,6
jne short mr_not_6chanbrk
mov ecx,eax
shr ecx,1
add eax,ecx
mr_not_6chanbrk:
add currow,eax
mov rowleft,64
mov _currow,0
mov break,0
mr_nonewrow:
mov al,tempo
mov tempoc,al
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; fx_???? effects handler called in between rows (called every IRQ)
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
fx_between_rows:
mov ebp,ordwidth
dec ebp
fx_mainloop:
mov dx,[effect+ebp*2]
test dx,dx
je fx_doneeffect
cmp dh,0ah ; volume slide
jne short fx_portamento_up
mov dh,dl
and dl,0fh
shr dh,3 ; 4
mov al,[ebp+modvol]
sub al,dl
cmp al,65
jb short fx_vollow
xor al,al
fx_vollow:
add al,dh
cmp al,64
jbe short fx_volhigh
mov al,64
fx_volhigh:
mov [ebp+modvol],al
cmp al,63
jb short fx_not64
mov al,63
fx_not64:
shr al,2
mov _vcvol[ebp],al
or _vccmnd[ebp],vol
jmp fx_doneeffect
fx_portamento_up:
cmp dh,01h ; portup
jne short fx_portamento_down
xor dh,dh
mov bx,period[ebp*2]
sub bx,dx
cmp bx,57
jae short fx_notbelow
mov bx,57
fx_notbelow:
mov period[ebp*2],bx
sub ebx,57
and ebx,0fffeh
mov bx,pitchtbl[ebx]
mov _vcfreq[ebp*2],bx
or _vccmnd[ebp],freq
jmp fx_doneeffect
fx_portamento_down:
cmp dh,02h ; portdown
jne short fx_volumeslide
xor dh,dh
mov bx,period[ebp*2]
add bx,dx
cmp bx,1711
jb short fx_nooverflow
mov bx,1711
fx_nooverflow:
mov period[ebp*2],bx
sub ebx,57
and ebx,0fffeh
mov bx,pitchtbl[ebx]
mov _vcfreq[ebp*2],bx
or _vccmnd[ebp],freq
jmp fx_doneeffect
fx_volumeslide:
cmp dh,05h ; handle volume slide
jne short fx_tone_slide
mov dh,dl
and dl,0fh
shr dh,3 ; 4
mov al,[ebp+modvol]
sub al,dl
cmp al,65
jb fx_volunder
xor al,al
fx_volunder:
add al,dh
cmp al,64
jbe fx_volover
mov al,64
fx_volover:
mov [ebp+modvol],al
cmp al,63
jb short fx_vol63
mov al,63
fx_vol63:
shr al,2
mov _vcvol[ebp],al
or _vccmnd[ebp],vol
mov dh,3
mov dl,[portparm+ebp]
fx_tone_slide:
cmp dh,3 ; tone slide
jne fx_vibrato
xor dh,dh
mov ax,[ebp*2+portto]
mov bx,[ebp*2+period]
cmp bx,ax
je fx_doneeffect
jg short fx_toneup
fx_tonedown:
add bx,dx
cmp bx,ax
jle short fx_settone
fx_underflow:
mov bx,ax
jmp short fx_settone
fx_toneup:
sub bx,dx
cmp bx,ax
jl short fx_underflow
fx_settone:
mov [ebp*2+period],bx
sub bx,57
and ebx,0fffeh
mov ax,pitchtbl[ebx]
mov _vcfreq[ebp*2],ax
or _vccmnd[ebp],freq
jmp fx_doneeffect
fx_vibslide:
cmp dh,6 ; volume slide + vibrato
jne fx_vibrato
mov dh,dl
and dl,0fh
shr dh,3 ; 4
mov al,[ebp+modvol]
sub al,dl
cmp al,65
jb short fx_vlunder
xor al,al
fx_vlunder:
add al,dh
cmp al,64
jbe short fx_vlover
mov al,64
fx_vlover:
mov [ebp+modvol],al
cmp al,63
jb short fx_vl63
mov al,63
fx_vl63:
shr al,2
mov _vcvol[ebp],al
or _vccmnd[ebp],vol
mov dh,4
mov dl,vibparm[ebp]
fx_vibrato:
cmp dh,4 ; vibrato
jne fx_arp
mov dh,dl
and dl,0fh
shr dh,4
shl dh,2
add [ebp+vibpos],dh
mov dh,[ebp+vibpos]
mov bl,dh
shr bl,2
and ebx,1fh
mov al,[sintable+ebx]
mul dl
rol ax,1
xchg al,ah
and ah,1
test dh,dh
jns fx_vibup
neg ax
fx_vibup:
add ax,[ebp*2+period]
mov bx,ax
cmp bx,57
jge short fx_nolovib
mov bx,57
fx_nolovib:
cmp bx,1712
jle short fx_nohivib
mov bx,1712
fx_nohivib:
sub ebx,57
and ebx,0fffeh
mov ax,pitchtbl[ebx]
mov _vcfreq[ebp*2],ax
or _vccmnd[ebp],freq
jmp fx_doneeffect
fx_arp:
cmp dh,0 ; arpeggio
jne fx_more_effects
xor ebx,ebx
mov bl,byte ptr [ebp*8+arp]
mov ax,word ptr [ebp*8+arp+ebx+2]
mov _vcfreq[ebp*2],ax
or _vccmnd[ebp],freq
add bl,2
cmp bl,6
jb short fx_setarp
xor bl,bl
fx_setarp:
mov byte ptr [ebp*8+arp],bl
jmp fx_doneeffect
fx_more_effects:
; Put more effects here
; dh = effect
; dl = data
fx_doneeffect:
dec ebp
jnl fx_mainloop
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Init mod player
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_mod_init:
ret ; nothing to init!
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Reset mod player
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_mod_uninit:
call _mod_stop
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Load a mod, samples go directly into GUS ram
; In:
; EAX -> stream input routine (In:ECX=len,EDX->buf, Out:EAX=len,CF=1 error)
; EDX -> buffer large enough for all music data plus largest sample
; _sfxmem -> location to begin storing on GUS memory
; Out:
; CF = 1 mod not recognized!
; CF = 0 mod loaded ok!
; EAX - number of bytes of buffer to keep
; EBX - number of bytes used on GUS
; _sfxmem -> next free GUS memory location
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_mod_load:
pushad
mov sambase,edx
mov ecx,1084
call eax
mov eax,4
mov ebx,[edx+1080]
cmp ebx,"4TLF"
je ml_foundtype
cmp ebx,".K.M"
je ml_foundtype
cmp ebx,"!K!M"
je ml_foundtype
mov al,6
cmp ebx,"6TLF"
je ml_foundtype
cmp ebx,"NHC6"
je ml_foundtype
mov al,8
cmp ebx,"8TLF"
je ml_foundtype
cmp ebx,"NHC8"
je ml_foundtype
popad ; unknown module type
stc
ret
ml_foundtype:
mov ordwidth,eax
mov al,[edx+950]
mov lastord,al
mov ecx,31
lea esi,[edx+20]
mov edi,edx
ml_sampledata:
movzx eax,word ptr [esi+22]
xchg ah,al
shl eax,1
stosd ; sample length
movzx eax,word ptr [esi+24]
stosd
movzx eax,word ptr [esi+26]
xchg ah,al
shl eax,1
stosd ; sample repeat start
movzx eax,word ptr [esi+28]
xchg ah,al
shl eax,1
stosd ; repeat length
add esi,30
loop ml_sampledata
mov ordbase,edi
mov ecx,128
lea esi,[edx+952]
xor al,al
ml_rep:
mov ah,[esi] ; copy pattern order
mov [edi],ah ; and find highest pattern number
cmp ah,al
jb ml_notl
mov al,ah
ml_notl:
inc esi
inc edi
loop ml_rep
mov patterns,edi
inc al
mov ordsize,al
mov edx,edi
mov ecx,ordwidth
shl ecx,6+2
movzx eax,ordsize
imul ecx,eax
call dword ptr [esp+28]
add edx,ecx
mov patternend,edx
mov ebx,_sfxmem
mov esi,sambase
mov edi,31
mov _sfxsign,80h
ml_loop1:
mov ecx,[esi] ; [esi+0] = length
jcxz ml_nextsample ; [esi+8] = repeat start
cmp ecx,[esi+12] ; [esi+12] = repeat length
ja ml_nofixl ; ebx = GUS memory, ecx = length
mov [esi+12],ecx
ml_nofixl:
mov eax,[esi+8]
add eax,[esi+12]
cmp eax,ecx
jb mr_nofixr
mov eax,ecx
sub eax,[esi+12]
mov [esi+8],eax
mr_nofixr:
mov ebp,ecx
mov eax,[esi+12]
cmp eax,4
jb short ml_noloop
or byte ptr [esi+4+2],loop_on+loop_bi
mov ebp,eax
add ebp,[esi+8]
ml_noloop:
mov [esi],ebx
add [esi+8],ebx
add ebp,ebx
mov [esi+12],ebp
call dword ptr [esp+28]
call _sfx_putram
add ebx,ecx
ml_nextsample:
add esi,4*4
dec edi
jnz ml_loop1
mov edx,sambase
sub edx,patternend
mov [esp+28],edx
mov [esp+16],ebx ; save amount of GUS ram used for samples
add _sfxmem,ebx
mov ebp,57
xor eax,eax
ml_findpitch:
cmp bp,periods[eax*2]
jae ml_set_freq
inc eax
cmp eax,930
jne ml_findpitch
ml_set_freq:
mov ax,rawfreq[eax*2]
call _sfx_getfreq
mov ecx,ebp
sub ecx,57
and ecx,0fffeh
mov pitchtbl[ecx],ax
add ebp,2
xor eax,eax
cmp ebp,1713
jb ml_findpitch
popad
clc ; clc = mod OK!
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Play a loaded mod
; In:
; EAX = routine to call when done module
; eg: _ret = loop module forever.
; _mod_stop = stop module when done
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_mod_play:
push eax ecx edi esi
call _mod_stop
mov whendone,eax
mov _ordmod,0
mov tempo,6
mov tempoc,1
mov panloc,0
mov rowleft,64
mov _currow,0
mov esi,ordbase
movzx eax,byte ptr [esi]
shl eax,10
add eax,patterns
mov currow,eax
call _irq_findcontrol
jc short mp_nomod
mov _irqcontrol[ecx*4],offset mr_modpolling
mov whichmodcontrol,ecx
mp_nomod:
xor eax,eax
mov edi,offset effect
mov ecx,8
rep stosw
mov edi,offset cursamp
mov ecx,152
rep stosb
mov edi,offset modvol
mov eax,64
mov ecx,8
rep stosb
pop esi edi ecx eax
clc
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Stop playback
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_mod_stop:
push ecx
mov dword ptr _vcvol[0],0000000h
mov dword ptr _vcvol[4],0000000h
mov dword ptr _vccmnd[0],20202020h
mov dword ptr _vccmnd[4],20202020h
mov ecx,whichmodcontrol
or ecx,ecx
jl ms_ret
mov _irqcontrol[ecx*4],offset _ret
mov whichmodcontrol,-1
ms_ret:
pop ecx
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Play mod sample # al
; In: AL sample play
; DL = channel (0-31)
; BL = volume (0-15)
; BH = pan (0-8)
; CH = precalculated frequency (0-59)
; Out:
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_mod_sample_play:
pushad
movzx eax,al
mov esi,sambase
shl eax,4
add esi,eax
mov edi,[esi]
mov eax,[esi+8]
mov ebp,[esi+12]
mov _vcsbeg[edx*4],edi
mov _vclbeg[edx*4],eax
mov _vclend[edx*4],ebp
mov cl,byte ptr [esi+4+2]
mov _vcpan[edx],bh
mov _vcvol[edx],bl
movzx eax,ch
mov ax,_freqtbl[eax*2]
mov _vcfreq[edx*2],ax
mov _vccntrl[edx],cl
mov _vccmnd[edx],play ; command comes last
popad
ret
code32 ends
end